package com.pe.pgn.clubpgn.dao.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.pe.pgn.clubpgn.common.CLPConstantes;
import com.pe.pgn.clubpgn.dao.TarjetaEmpresaDao;
import com.pe.pgn.clubpgn.dao.hibernate.GenericDaoHibernate;
import com.pe.pgn.clubpgn.domain.ClpbTarjetaEmpresa;
import com.pe.pgn.clubpgn.domain.beans.BNTarjetaEmpresa;
import com.pe.pgn.clubpgn.util.StringUtil;

@Repository("tarjetaEmpresaDao")
public class TarjetaEmpresaDaoImpl extends GenericDaoHibernate<ClpbTarjetaEmpresa, Long> 
		implements TarjetaEmpresaDao{
	
	public TarjetaEmpresaDaoImpl() {
		super(ClpbTarjetaEmpresa.class);
	}
	
	private JdbcTemplate jdbcTemplate;

	@Autowired
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}

	@SuppressWarnings("unchecked")
	public List<ClpbTarjetaEmpresa> obtenerTarjetasEmpresa() {

		Criteria criteria = DetachedCriteria.forClass(ClpbTarjetaEmpresa.class)
		.getExecutableCriteria(getSessionFactory().getCurrentSession());

		criteria.setMaxResults(CLPConstantes.MAXIMO_RESULTADO_INICIAL);
		criteria.addOrder(Order.desc("id"));
		
		List<ClpbTarjetaEmpresa> lista = criteria.list(); 
		return lista;
	}
	
	@SuppressWarnings("unchecked")
	public List<BNTarjetaEmpresa> buscarTarjetasEmpresas(BNTarjetaEmpresa tarjetaEmpresa, boolean esInicial){
		
		StringBuffer query = new StringBuffer();		
		query.append("select te.id as id, ");
		query.append("		te.co_codigo_tarjeta_empresa as coCodigoTarjetaEmpresa, ");
		query.append("		fv.de_placa as dePlaca,");
		query.append("		f.de_flota_area as deNombreFlota, ");
		query.append("		ce.de_cliente_empresa as deNombre, ");
		query.append("		ce.co_ruc as deRuc, ");
		query.append("		to_char(te.da_fecha_inicio_vigencia, 'dd/MM/yyyy') as daVigenciaInicio,");
		query.append("		to_char(te.da_fecha_fin_vigencia, 'dd/MM/yyyy') as daVigenciaFin, ");
		query.append("		te.st_tarjeta_empresa as stTarjetaEmpresa, ");
		query.append("		to_char(te.da_fecha_anulacion, 'dd/MM/yyyy') as daFechaAnulacion ");
		query.append("	from clpb_tarjeta_empresa te left outer join clpr_flota_vehiculo fv  on te.co_flota_vehiculo = fv.id ");
		query.append("    left outer join clpd_flota f on fv.co_flota = f.id ");
		query.append("    left outer join clpb_cliente_empresa ce on f.co_cliente_empresa = ce.id ");
		query.append("	where 1 = 1 ");
		
		if(tarjetaEmpresa != null){
			
			if(StringUtils.isNotBlank(tarjetaEmpresa.getCoCodigoTarjetaEmpresa())){
				query.append("		and te.co_codigo_tarjeta_empresa like '%")
							.append(tarjetaEmpresa.getCoCodigoTarjetaEmpresa().trim()).append("%' ");
			}
			
			if(StringUtils.isNotBlank(tarjetaEmpresa.getDeNombre())){
				query.append("		and upper(trim(ce.de_cliente_empresa))  like '%")
							.append(tarjetaEmpresa.getDeNombre().trim().toUpperCase()).append("%' ");
			}
			
			if(StringUtils.isNotBlank(tarjetaEmpresa.getDePlaca())){
				query.append("		and upper(trim(fv.de_placa)) like '%")
							.append(tarjetaEmpresa.getDePlaca().trim().toUpperCase()).append("%' ");
			}
			
			String stTarjetaEmpresa = tarjetaEmpresa.getStTarjetaEmpresa();
			if(StringUtils.isNotBlank(stTarjetaEmpresa) 
					&& !stTarjetaEmpresa.equalsIgnoreCase(CLPConstantes.CARACTER_GUION_NO_ESPACIOS)){
				query.append("		and te.st_tarjeta_empresa = '").append(tarjetaEmpresa.getStTarjetaEmpresa()).append("' ");
			}
		}	
		
		if(esInicial){
			
//			query.append("	and st_tarjeta_empresa = '").append(CLPConstantes.ST_VERDADERO).append("' ");			
			query.append("	order by te.id desc ");
			
			StringBuffer prequery = new StringBuffer();
			prequery.append(" select * from (").append(query.toString()).append(") where rownum <= " + CLPConstantes.MAXIMO_RESULTADO_INICIAL);
			
			query = new StringBuffer(prequery.toString());		
		}	
		else{
			
			query.append("	order by te.id desc ");
		}
		
		List lista = findListOfBeans(query.toString(), null, BNTarjetaEmpresa.class);
		return lista;

	}

	public BigDecimal obtenerMaximoCodigoTarjetaEmpresa() {
		
		StringBuilder sql = new StringBuilder();		
		sql.append(" select max(to_number(substr(co_codigo_tarjeta_empresa, 2))) " );
		sql.append(" from clpb_tarjeta_empresa  ");
		
		BigDecimal codigoMaximo = jdbcTemplate.queryForObject(sql.toString(), BigDecimal.class);
		if(codigoMaximo == null){
			return BigDecimal.ZERO;
		}
		
		return codigoMaximo;
	}

	public boolean existeRango(BNTarjetaEmpresa tarjetaEmpresa) {
		StringBuffer query = new StringBuffer();
		query.append("select count(*) ");
		query.append("	from clpb_tarjeta_empresa ");
		query.append("	where to_number(substr(co_codigo_tarjeta_empresa, 2)) between ").append(tarjetaEmpresa.getNumeroInicio());
		query.append("		and ").append(tarjetaEmpresa.getNumeroFin());

		int count = jdbcTemplate.queryForInt(query.toString());
        
		if(count > 0){
			return true;
		}
		return false;
	}

	public void guardarGrupoTarjetasEmpresas(BNTarjetaEmpresa tarjetaEmpresa) {
		
		BigDecimal inicio = tarjetaEmpresa.getNumeroInicio();
		BigDecimal fin = tarjetaEmpresa.getNumeroFin();
		
		List<ClpbTarjetaEmpresa> tarjetas = new ArrayList<ClpbTarjetaEmpresa>();
		while (inicio.compareTo(fin) <= 0){

			String codigo =  StringUtil.getStringLeftPad(inicio.toString(), CLPConstantes.LONGITUD_MAXIMA_NUMERO_TARJETA_EMPRESA, 
					CLPConstantes.CODIGO_RELLENO_TARJETA_PERSONA, CLPConstantes.PREFIJO_TARJETA_EMPRESA);
			
			ClpbTarjetaEmpresa clpbTarjetaEmpresa = new ClpbTarjetaEmpresa();
			clpbTarjetaEmpresa.setCoCodigoTarjetaEmpresa(codigo);
			clpbTarjetaEmpresa.setDaFechaInicioVigencia(tarjetaEmpresa.getDaFechaInicioVigencia());
			clpbTarjetaEmpresa.setDaFechaFinVigencia(tarjetaEmpresa.getDaFechaFinVigencia());
			clpbTarjetaEmpresa.setDeObservaciones(tarjetaEmpresa.getDeObservaciones());
			clpbTarjetaEmpresa.setStTarjetaEmpresa(Boolean.TRUE);
			clpbTarjetaEmpresa.setStBloqueado(Boolean.FALSE);
			
			clpbTarjetaEmpresa.setCoUsuarioCreador(getUsuarioLogueado().getUsername());
			clpbTarjetaEmpresa.setDaFechaCreacion(Calendar.getInstance());
			
			inicio = inicio.add(BigDecimal.ONE);
			tarjetas.add(clpbTarjetaEmpresa);
		}
		
		getHibernateTemplate().saveOrUpdateAll(tarjetas);
		getHibernateTemplate().flush();
	}

	public ClpbTarjetaEmpresa obtenerTarjetaEmpresa(Long id) {
		
		ClpbTarjetaEmpresa tarjetaEmpresa = getHibernateTemplate().get(ClpbTarjetaEmpresa.class, id);
		return tarjetaEmpresa;
	}

	@SuppressWarnings("unchecked")
	public Map<String, Object> obtenerDatosClientePorFlota(Long coFlotaVehiculo) {
		
		StringBuffer query = new StringBuffer();
		query.append(" select fv.id as id, ");		
		query.append("		fv.de_placa as dePlaca,  ");
		query.append("		f.de_flota_area as deFlotaArea,  ");
		query.append("		ce.de_cliente_empresa as deClienteEmpresa ");
		query.append("	from clpr_flota_vehiculo fv join clpd_flota f on fv.co_flota = f.id  ");
		query.append("    join clpb_cliente_empresa ce on f.co_cliente_empresa = ce.id  ");
		query.append("	where fv.id = ").append(coFlotaVehiculo);
		
		List lista = findListOfMaps(query.toString(), null);
		if(!lista.isEmpty()){
			
			return (Map) lista.get(0);
		}		
		return null;
	}

	@SuppressWarnings("unchecked")
	public void actualizarTarjetaEmpresa(ClpbTarjetaEmpresa tarjetaEmpresa) {
		
		StringBuffer query = new StringBuffer();
		query.append("select st_tarjeta_empresa from clpb_tarjeta_empresa where id = ").append(tarjetaEmpresa.getId());
		List list = findListOfArrays(query.toString(), null);
		String stTarjetaEmpresa = "";
		if(!list.isEmpty()){
			
			Object [] array = (Object[]) list.get(0);
			stTarjetaEmpresa = array[0].toString();			
		}
		
		query = new StringBuffer();
		query.append("update clpb_tarjeta_empresa set de_observaciones = '").append(tarjetaEmpresa.getDeObservaciones());
		query.append("', st_tarjeta_empresa = '").append(tarjetaEmpresa.isStTarjetaEmpresa() ? 
													CLPConstantes.ST_VERDADERO : CLPConstantes.ST_FALSO);
		query.append("', st_bloqueado = '").append(tarjetaEmpresa.isStBloqueado() ? 
				CLPConstantes.ST_VERDADERO : CLPConstantes.ST_FALSO);
		query.append("', co_usuario_modificador = '").append(getUsuarioLogueado().getUsername());
		query.append("', da_fecha_modificacion = sysdate ");
		
		if(stTarjetaEmpresa.equalsIgnoreCase(CLPConstantes.ST_VERDADERO) 
				&& !tarjetaEmpresa.isStTarjetaEmpresa()){
			query.append(", da_fecha_anulacion = sysdate ");
		}
		
		query.append("where id = ").append(tarjetaEmpresa.getId());
		
		jdbcTemplate.update(query.toString());	
		
		
		if(stTarjetaEmpresa.equalsIgnoreCase(CLPConstantes.ST_VERDADERO) 
				&& !tarjetaEmpresa.isStTarjetaEmpresa()){
			
			query = new StringBuffer();
			query.append("select id from clpr_flota_vehiculo where co_tarjeta_empresa = ").append(tarjetaEmpresa.getId());
			list = findListOfArrays(query.toString(), null);
			if(!list.isEmpty()){
				
				Object [] array = (Object[]) list.get(0);
				String coFlotaVehiculo = array[0].toString();
				
				query = new StringBuffer();
				query.append("update clpr_flota_vehiculo set st_flota_vehiculo = '").append(CLPConstantes.ST_FALSO).append("' ");
				query.append("	where id = ").append(coFlotaVehiculo);
				jdbcTemplate.update(query.toString());				
			}
		}
	}
	
	public int esTarjetaValida(String coCodigoTarjetaEmpresa, Long coFlotaVehiculo) {
		
		StringBuffer query = new StringBuffer();		
		query.append(" select id  ");	
		query.append(" 	from clpb_tarjeta_empresa ");
		query.append(" 	where 1 = 1 ");
		query.append(" 	and trim(co_codigo_tarjeta_empresa) = '"+coCodigoTarjetaEmpresa.trim()+"'");
		query.append(" 	and st_tarjeta_empresa = '"+CLPConstantes.ST_VERDADERO+"'  ");
		query.append(" 	and st_bloqueado = '"+CLPConstantes.ST_FALSO+"'  ");
		
		Long idTarjetaEmpresa = null;
		List<Long> list = jdbcTemplate.queryForList(query.toString(), Long.class);
		if(!list.isEmpty()){						
			idTarjetaEmpresa = list.get(0);
		}
		else{			
			return CLPConstantes.TARJETA_EMPRESA_NO_EXISTE_O_NO_HABILITADA;
		}
		
		query = new StringBuffer();		
		query.append(" select count(*) ");
		query.append(" from clpr_flota_vehiculo ");
		query.append(" where co_tarjeta_empresa in (").append(idTarjetaEmpresa).append(") ");
		
		if(coFlotaVehiculo != null){
			query.append("	and id != ").append(coFlotaVehiculo);
		}
				
		int count = jdbcTemplate.queryForInt(query.toString());
		if (count > 0){
			return CLPConstantes.TARJETA_EMPRESA_USADA;
		}	
		
		return CLPConstantes.TARJETA_EMPRESA_VALIDA;
	}

	public Long obtenetId(String coCodigoTarjetaEmpresa) {
		
		StringBuffer query = new StringBuffer();		
		query.append(" select id  ");	
		query.append(" from clpb_tarjeta_empresa ");
		query.append(" where trim(co_codigo_tarjeta_empresa) ='"+coCodigoTarjetaEmpresa.trim()+"' ");
		query.append(" and st_tarjeta_empresa = '"+CLPConstantes.ST_VERDADERO+"'  ");
	
		Long idTarjetaEmpresa  = jdbcTemplate.queryForLong(query.toString());
		
		System.out.println(query.toString());
		
		if (null == idTarjetaEmpresa){
			
			return new Long(0);
		} 
		return idTarjetaEmpresa;
	}

	@SuppressWarnings("unchecked")
	public Map<String, Object> obtenerMapValidacionTarjeta(String cadenaTarjetas) {

		Map<String, Object> map = new HashMap<String, Object>();
		StringBuffer query = new StringBuffer();
		
		query.append(" select ");
		query.append(" 	id,	");
		query.append(" 	st_bloqueado as stBloqueado,			");
		query.append("	co_flota_vehiculo as coFlotaVehiculo, 	");
		query.append("	st_tarjeta_empresa as stTarjetaEmpresa,	");
		query.append("	co_codigo_tarjeta_empresa as coCodigoTarjetaEmpresa ");
		query.append(" from clpb_tarjeta_empresa ");
		query.append(" where trim(co_codigo_tarjeta_empresa) in ("+cadenaTarjetas+")");
		
		List<BNTarjetaEmpresa> list = findListOfBeans(query.toString(),null,BNTarjetaEmpresa.class);
		if(!list.isEmpty()){
			
			for (BNTarjetaEmpresa bnTarjetaEmpresa : list) {
				
				if(bnTarjetaEmpresa.getStBloqueado().equals(CLPConstantes.ST_VERDADERO)){
					
					map.put(bnTarjetaEmpresa.getCoCodigoTarjetaEmpresa(), CLPConstantes.TARJETA_EMPRESA_BLOQUEADA);
					
				}else if(bnTarjetaEmpresa.getStTarjetaEmpresa().equals(CLPConstantes.ST_FALSO)){
					
					map.put(bnTarjetaEmpresa.getCoCodigoTarjetaEmpresa(), CLPConstantes.TARJETA_EMPRESA_NO_EXISTE_O_NO_HABILITADA);
					
				}else if(bnTarjetaEmpresa.getCoFlotaVehiculo() != null){
					
					map.put(bnTarjetaEmpresa.getCoCodigoTarjetaEmpresa(), CLPConstantes.TARJETA_EMPRESA_USADA);
					
				}else{
					
					map.put(bnTarjetaEmpresa.getCoCodigoTarjetaEmpresa(), CLPConstantes.TARJETA_EMPRESA_VALIDA);
				}
			}			
		}
		
		return map;
	}	
}
